/**
 * ═══════════════════════════════════════════════════════════════════════════
 *                   P5.JS 生成艺术——最佳实践
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * 本文件展示 p5.js 生成艺术的结构与原则，
 * 而非规定你必须创作哪种作品。
 *
 * 你的算法哲学应当引领作品，以下仅是代码组织的最佳实践。
 *
 * ═══════════════════════════════════════════════════════════════════════════
 */

// ============================================================================
// 1. 参数组织
// ============================================================================
// 将所有可调参数集中放在一个对象中，方便：
// - 绑定到 UI 控件
// - 恢复默认值
// - 序列化/保存配置

let params = {
    // 定义契合你算法的参数
    // 示例（请根据作品自定义）：
    // - 数量：元素个数（粒子、圆、分枝等）
    // - 尺度：大小、速度、间距
    // - 概率：事件发生的可能性
    // - 角度：旋转、方向
    // - 色彩：调色板数组

    seed: 12345,
    // 推荐将 colorPalette 定义为数组，可任选颜色，如 ['#d97757', '#6a9bcc', '#788c5d', '#b0aea5']
    // 按照算法需求在此添加你的参数
};

// ============================================================================
// 2. 带种子随机（可复现性的关键）
// ============================================================================
// Art Blocks 级别的可复现输出必须使用带种子的随机

function initializeSeed(seed) {
    randomSeed(seed);
    noiseSeed(seed);
    // 之后的 random() 与 noise() 调用将具备确定性
}

// ============================================================================
// 3. P5.JS 生命周期
// ============================================================================

function setup() {
    createCanvas(800, 800);

    // 先初始化种子
    initializeSeed(params.seed);

    // 在此初始化生成系统，例如：
    // - 对象数组
    // - 网格结构
    // - 初始位置
    // - 初始状态

    // 如果是静态作品：在 setup 末尾调用 noLoop()
    // 如果是动画作品：让 draw() 持续运行
}

function draw() {
    // 方案一：静态生成（运行一次后停止）
    // - 在 setup() 中生成所有内容
    // - 在 setup() 中调用 noLoop()
    // - draw() 保持空或仅作少量处理

    // 方案二：动画生成（持续更新）
    // - 每帧更新系统状态
    // - 常见模式：粒子运动、增长、演化
    // - 可在 N 帧后调用 noLoop() 结束

    // 方案三：用户触发的再次生成
    // - 默认使用 noLoop()
    // - 当参数变化时调用 redraw()
}

// ============================================================================
// 4. 类结构（涉及多实体时）
// ============================================================================
// 当算法包含多个实体时可使用类，例如粒子、智能体、细胞、节点等

class Entity {
    constructor() {
        // 初始化实体属性
        // 此处可安全使用 random() —— 已绑定种子
    }

    update() {
        // 更新实体状态，可能包括：
        // - 物理计算
        // - 行为规则
        // - 与邻居的交互
    }

    display() {
        // 绘制实体
        // 建议将渲染逻辑与状态更新分离
    }
}

// ============================================================================
// 5. 性能考量
// ============================================================================

// 当元素较多时：
// - 能预先计算的尽量提前计算
// - 使用简单的碰撞检测（必要时可用空间哈希）
// - 尽量减少昂贵运算（如平方根、三角函数）
// - 合理使用 p5.Vector

// 为保持动画流畅：
// - 目标帧率 60fps
// - 出现性能瓶颈时进行性能分析
// - 适当降低粒子数量或简化计算

// ============================================================================
// 6. 工具函数
// ============================================================================

// 色彩工具
function hexToRgb(hex) {
    const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return result ? {
        r: parseInt(result[1], 16),
        g: parseInt(result[2], 16),
        b: parseInt(result[3], 16)
    } : null;
}

function colorFromPalette(index) {
    return params.colorPalette[index % params.colorPalette.length];
}

// 映射与缓动
function mapRange(value, inMin, inMax, outMin, outMax) {
    return outMin + (outMax - outMin) * ((value - inMin) / (inMax - inMin));
}

function easeInOutCubic(t) {
    return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
}

// 边界循环
function wrapAround(value, max) {
    if (value < 0) return max;
    if (value > max) return 0;
    return value;
}
